package com.jplus.framework.util;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池工具类 <br/>
 * Java通过Executors提供四种线程池，分别为：<br>
 * newCachedThreadPool创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。<br>
 * newFixedThreadPool 创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。<br>
 * newScheduledThreadPool 创建一个定长线程池，支持定时及周期性任务执行。<br>
 * newSingleThreadExecutor 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO,
 * LIFO, 优先级)执行。
 * 
 * @author Yuanqy
 *
 */
public class ThreadPoolUtil {

	private static ExecutorService service = null;
	private static BlockingQueue<Runnable> queue = null;

	/**
	 * 初始化有界队列
	 * @param nThreads
	 * @param queueSize
	 */
	public static synchronized void init(int nThreads, int queueSize) {
		if (service == null) {
			queue = new ArrayBlockingQueue<>(10000);// 数组 有界队列
			service = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, queue);
		}
	}

	/**
	 * 初始化线程池，并设置线程池大小
	 * 
	 * @param nThreads
	 */
	public static synchronized void init(int nThreads) {
		if (service == null) {
			queue = new LinkedBlockingQueue<>();// 链表 无界队列,【默认】
			service = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, queue);
			// service = Executors.newFixedThreadPool(nThreads); //等同于
		}
	}

	/**
	 * 获取队列数
	 * @return
	 */
	public static int getQueueSize() {
		return queue.size();
	}

	/**
	 * 线程池实例化
	 * @return
	 */
	private static ExecutorService getInstance() {
		if (service == null)
			throw new NullPointerException("线程池未初始化，请先初始化！");
		return service;
	}

	/**
	 * 将任务加入线程执行
	 */
	public static boolean execute(Runnable runnalbe) {
		boolean flag = true;
		try {
			getInstance().execute(runnalbe);
		} catch (Exception e) {
			e.printStackTrace();
			flag = false;
		}
		return flag;
	}

	/**
	 * 待所有线程执行完毕后关闭线程池
	 */
	public static void shutdown() {
		if (service != null) {
			System.err.println("=========[警告]线程池正在关闭[待所有线程执行完毕后]============");
			service.shutdown();
		}
	}

	/**
	 * 强制当前立即关闭线程池
	 */
	public static void shutdownNow() {
		if (service != null) {
			System.err.println("=========[警告]线程池正在关闭[强制当前立即关闭]============");
			service.shutdownNow();
		}
	}
}
